package com.zx.sercurity;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

/**
 * 无障碍风险
 */
public class AccessibilityServiceRisk implements RiskControlInterface<RiskResult.AccessibilityServiceRiskResult> {

    private static final String TAG = "ASRisk";
    //主流输入法包名
    private final List<String> softInputDashboard = Arrays.asList(
            "com.baidu.input", //百度
            "com.iflytek.inputmethod", //讯飞
            "com.tencent.qqpinyin", //腾讯：
            "com.google.android.inputmethod.latin", //谷歌
            "com.sohu.inputmethod.sogou", //搜狗
            "com.android.inputmethod.latin"// 原生
    );

    @Override
    public RiskResult.AccessibilityServiceRiskResult riskCheck(Context context) {
        if (checkAccessibilityServiceOpen(context)) {//检查是否开启了无障碍模式
            //获取所有已经开启无障碍的服务信息
            List<AccessibilityServiceInfo> installedAccessibilityApk = new ArrayList<>(getInstalledAccessibilityApk(context));
            //所有的输入法包名
            HashSet<String> softInputDashboardPackages = new HashSet<>();
            //拿到当前使用的输入法包名
            for (InputMethodInfo inputMethodInfo : getNowEnabledSoftInputDashboardPackage(context)) {
                softInputDashboardPackages.add(inputMethodInfo.getPackageName());
            }
            //加上主流的输入法包名，hashset自动去重
            softInputDashboardPackages.addAll(softInputDashboard);

            //放置系统包名及输入法包名
            List<AccessibilityServiceInfo> systemOrInputService = new ArrayList<>();
            try {//遍历启用的无障碍应用
                for (AccessibilityServiceInfo accessibilityServiceInfo : installedAccessibilityApk) {
                    //得到包名
                    String packageName = accessibilityServiceInfo.getResolveInfo().serviceInfo.packageName;
                    //得到应用信息
                    ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
                    //判断是否是系统应用或者输入法
                    if (isSystemApk(appInfo) || softInputDashboardPackages.contains(packageName)) {
                        systemOrInputService.add(accessibilityServiceInfo);
                        Log.i(TAG, "sys packageName: " + packageName);
                    } else {
                        Log.i(TAG, "other packageName: " + packageName);
                    }
                }
            } catch (PackageManager.NameNotFoundException exception) {
                Log.i(TAG, Arrays.toString(exception.getStackTrace()));
            }

            //从所有的无障碍应用列表当中移除掉所有的系统应用和输入法应用
            installedAccessibilityApk.removeAll(systemOrInputService);
            //如果列表仍然不为0，则为开启了第三方无障碍模式
            if (!installedAccessibilityApk.isEmpty()) {
                ArrayList<String> enabledAccessibilityServicePackages = new ArrayList<>();
                for (AccessibilityServiceInfo accessibilityServiceInfo : installedAccessibilityApk) {
                    enabledAccessibilityServicePackages.add(
                            accessibilityServiceInfo.getResolveInfo().serviceInfo.packageName
                    );
                }
                return new RiskResult.AccessibilityServiceRiskResult(enabledAccessibilityServicePackages);
            }
        }
        Log.i(TAG, "无障碍模式未开启");
        return new RiskResult.AccessibilityServiceRiskResult(false);
    }

    /**
     * @param context 上下文
     * @return 是否开启了无障碍模式
     */
    private boolean checkAccessibilityServiceOpen(Context context) {
        AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
        if (am == null) return false;
        Log.i(TAG, "checkAccessibilityServiceOpen: ");
        return am.isEnabled();
    }

    /**
     * @param context 上下文
     * @return 所有已开启无障碍服务的应用数据列表
     */
    private List<AccessibilityServiceInfo> getInstalledAccessibilityApk(Context context) {
        AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
        return am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
    }

    /**
     * 获取已经启用的输入法
     *
     * @param context 上下文
     * @return 已启用的输入法
     */
    private List<InputMethodInfo> getNowEnabledSoftInputDashboardPackage(Context context) {
        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputMethodManager == null) return Collections.emptyList();
        return inputMethodManager.getEnabledInputMethodList();
    }

    /**
     * @param appInfo AppInfo
     * @return 判断是否是系统app
     */
    private boolean isSystemApk(ApplicationInfo appInfo) {
        boolean isSystemApp = (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
        boolean isUpdatedSystemApp = (appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;

        return isSystemApp || isUpdatedSystemApp;
    }


}
